/* Wasson An
 * This class contains the panel on which the game is played for single player. 
 * The panel also runs the whole game.	
 */

package catandmouse;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;


public class MultiGamePanel implements CAM, ActionListener{

	private final int SPEED = 5; //the speed
	private final double ACCEL = .12; //acceleration

	private JButton connect; //connects client to server
	private JTextField host; //where user enters IP address of server
	private JTextField sockNum; //where user enters socket number

	private JFrame network; //displays prompt for networking info
	private Socket socket; //the socket number
	private BufferedReader input; //reads input from server
	private PrintWriter output; //sends output to server

	private JFrame game; //the window with the game
	private GamePanel gamePanel; //the game panel

	private Actor player; //the mouse
	private Actor other; //the cat
	private boolean up; //if the mouse is going up
	private boolean down; //if the mouse is going down
	private boolean left; //if the mouse is going left
	private boolean right; //if the mouse is going right
	private double pvSpeed; //player vertical speed
	private double phSpeed; //player horizontal speed
	private double count; //how many cycles you stayed alive
	private boolean isCat; //holds if the user is the cat


	//0 parameter constructor creating and running the game
	public MultiGamePanel(){

		game = new JFrame();
		game.setSize(1000, 720);
		game.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		game.setVisible(false);		

		this.setUpNetworking();
	}//default constructor


	//starts the game
	private void start(){

		//resets movement flags
		up = false;
		down = false;
		left = false;
		right = false;
		pvSpeed = 0;
		phSpeed = 0;

		count = 0;

		//places the player and cat
		int w = game.getWidth();
		int h = game.getHeight();

		System.out.println("Debug: Cheking position 2: " + isCat);
		
		if(isCat){
			
			player = new Actor(w / 3, h / 2, w, h);
			other = new Actor(2 * w / 3, h / 2, w, h);
		}//if
		
		else{
			
			other = new Actor(w / 3, h / 2, w, h);
			player = new Actor(2 * w / 3, h / 2, w, h);
		}//else
		if(isCat)
			gamePanel = new GamePanel(other.getPosition(), player.getPosition()
					, this, w, h);

		else
			gamePanel = new GamePanel(player.getPosition(), other.getPosition()
					, this, w, h);
		
		game.add(gamePanel);
		gamePanel.repaint();
		game.repaint();

		this.play();
	}//start


	//plays the game
	private void play(){

		String info = "";

		try{
			
			info = input.readLine();

			while(info.equals("N")){

				count++;

				System.out.println("Debug: Moving player");
				
				//moves the mouse
				if(down)
					pvSpeed += ACCEL;

				if(up)
					pvSpeed -= ACCEL;

				if(left)
					phSpeed -= ACCEL;

				if(right)
					phSpeed += ACCEL;

				if(pvSpeed < 0)
					pvSpeed += ACCEL / 3;

				else
					pvSpeed -= ACCEL / 3;

				if(phSpeed < 0)
					phSpeed += ACCEL / 3;

				else
					phSpeed -= ACCEL / 3;


				if(pvSpeed > SPEED)
					pvSpeed = SPEED;

				if(phSpeed > SPEED)
					phSpeed = SPEED;

				if(pvSpeed < SPEED * -1)
					pvSpeed = SPEED * -1;

				if(phSpeed < SPEED * -1)
					phSpeed = SPEED * -1;

				player.moveHorizontal((int)Math.round(phSpeed));
				player.moveVertical((int)Math.round(pvSpeed));

				System.out.println("Debug: Printing player position");
				
				output.println(player.getPosition().getX());
				output.println(player.getPosition().getY());
				output.flush();

				System.out.println("Debug: Reading other position");
				
				other.moveHorizontal(Integer.parseInt(input.readLine()) - 
						other.getPosition().getX());
				other.moveVertical(Integer.parseInt(input.readLine()) -
						other.getPosition().getY());

				System.out.println("Debug: Redrawing panel");
				
				if(isCat){

					gamePanel.setCPos(player.getPosition());
					gamePanel.setMPos(other.getPosition());
				}//if

				else{

					gamePanel.setMPos(player.getPosition());
					gamePanel.setCPos(other.getPosition());
				}//else

				gamePanel.setCount(count);
				gamePanel.repaint();		
				
				System.out.println("Debug: Checking status");
				
				info = input.readLine();
			}//while
			
			if(info.equals("W"))
				System.out.println("Win");
			
			else
				System.out.println("Lose");

		}catch(Exception e){

			System.out.println("Something went wrong playing the game. @2");
			System.exit(-1);
		}//catch
	}//play


	//creates frame to gain networking info from user
	private void setUpNetworking(){

		//initializes frame
		network = new JFrame();
		network.setTitle("Server/Client");
		network.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		network.setSize(225,125);
		network.setLayout(new FlowLayout());

		//initializes components of frame
		JLabel IP = new JLabel("Enter Host");
		JLabel port = new JLabel("Enter Port");
		connect = new JButton("Connect");
		connect.setActionCommand("Connect");
		host = new JTextField(10);
		sockNum = new JTextField(10);

		connect.addActionListener(this);

		//adds components to frame
		network.add(IP);
		network.add(host);
		network.add(port);
		network.add(sockNum);
		network.add(connect);

		network.setVisible(true);
	}


	//triggered when the timer ticks
	public void actionPerformed(ActionEvent ae) {

		if(ae.getActionCommand().equals("Connect")){

			String info = "";

			try{

				//connects to server
				socket = new Socket(host.getText(), Integer.parseInt(
						sockNum.getText()));
				input = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				output = new PrintWriter(socket.getOutputStream());

				//gains info from server
				info = input.readLine();

			} catch(Exception e){

				System.out.println("Unable to connect to server. @1");
				System.exit(-1);
			}

			if(info.equals("mouse"))
				isCat = false;

			else
				isCat = true;

			System.out.println("Debug: Checking position: " + isCat);
			
			network.setVisible(false);
			game.setVisible(true);

			this.start();
		}//if
	}//actionPerformed


	//when a key is pressed down
	public void keyPressed(KeyEvent e){

		if(e.getKeyCode() == KeyEvent.VK_UP)		
			up = true;

		else if(e.getKeyCode() == KeyEvent.VK_DOWN)
			down = true;

		else if(e.getKeyCode() == KeyEvent.VK_LEFT)
			left = true;

		else if(e.getKeyCode() == KeyEvent.VK_RIGHT)
			right = true;
	}//keyPressed


	//when a key is released
	public void keyReleased(KeyEvent e){

		if(e.getKeyCode() == KeyEvent.VK_UP)
			up = false;

		else if(e.getKeyCode() == KeyEvent.VK_DOWN)
			down = false;

		else if(e.getKeyCode() == KeyEvent.VK_LEFT)
			left = false;

		else if(e.getKeyCode() == KeyEvent.VK_RIGHT)
			right = false;
	}//keyPressed

	//when a key is typed
	public void keyTyped(KeyEvent arg0) {

	}//keyTyped


	public static void main(String[] args){

		new MultiGamePanel();
	}//main
}//GamePanel
